package com.ddwl.gate.service;

import com.alibaba.fastjson.JSON;
import com.ddwl.common.constant.BaseEnum;
import com.ddwl.common.constant.Constant;
import com.ddwl.common.constant.RedisKey;
import com.ddwl.common.exception.ParamException;
import com.ddwl.common.feign.api.UserApi;
import com.ddwl.common.feign.byteDance.ByteDanceApi;
import com.ddwl.common.service.RedisService;
import com.ddwl.schema.bo.gate.byteDance.ByteOrderBo;
import com.ddwl.schema.bo.gate.byteDance.ByteQRCodeBo;
import com.ddwl.schema.bo.gate.byteDance.ByteRefundBo;
import com.ddwl.schema.vo.funds.ByteDanceOrderVo;
import com.ddwl.schema.vo.funds.ByteDanceQueryOrderVo;
import com.ddwl.schema.vo.funds.ByteDanceQueryRefundVo;
import com.ddwl.schema.vo.funds.ByteDanceRefundVo;
import com.ddwl.schema.vo.gate.byteDance.ByteDanceInfoVo;
import com.ddwl.schema.vo.gate.byteDance.ByteDanceSessionVo;
import com.ddwl.schema.vo.gate.byteDance.ByteDanceTokenVo;
import com.ddwl.schema.vo.user.RegisterBo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Author hemiaojun
 * @Date 2021/8/3 16:35
 */
@Slf4j
@Service
public class ByteDanceService {


    @Resource
    private RedisService redisService;
    @Resource
    private ByteDanceApi byteDanceApi;
    @Resource
    private UserApi userApi;
    @Resource
    private RestTemplate restTemplate;


    public String token() {
        String appId = BaseEnum.ByteDanceAppId.MICRO_APP.getCode();

        String token = redisService.getValueOps().get(RedisKey.BYTE_DANCE_TOKEN.getKey(appId));
        if (StringUtils.hasText(token)) {
            return token;
        }
        String secret = redisService.getHashOps().get(RedisKey.BYTE_DANCE_KEY.getKey(appId), "appSecret");
        ParamException.isTrue(!StringUtils.hasText(secret),"配置不存在");
        ByteDanceTokenVo byteDanceTokenVo = byteDanceApi.token(appId, secret, "client_credential");
        ParamException.isNotNull(byteDanceTokenVo.getError(),byteDanceTokenVo.getMessage());
        token = byteDanceTokenVo.getAccess_token();
        redisService.getValueOps().set(RedisKey.BYTE_DANCE_TOKEN.getKey(appId),token,byteDanceTokenVo.getExpires_in(), TimeUnit.SECONDS);
        return token;
    }

    public ByteDanceInfoVo login(String code,String product,String dk) {
        String appId = BaseEnum.ByteDanceAppId.MICRO_APP.getCode();
        ByteDanceSessionVo sessionVo = getByteDanceSession(appId,code);

        RegisterBo registerBo = new RegisterBo();
        registerBo.setByteOpenId(sessionVo.getOpenid());
        registerBo.setByteUnionId(sessionVo.getUnionid());
        registerBo.setProduct(product);
        registerBo.setDk(dk);
        registerBo.setAppId(appId);

        ByteDanceInfoVo byteDanceInfoVo = new ByteDanceInfoVo();
        byteDanceInfoVo.setOpenid(sessionVo.getOpenid());
        byteDanceInfoVo.setAnonymous_openid(sessionVo.getAnonymous_openid());
        byteDanceInfoVo.setUnionId(sessionVo.getUnionid());
        byteDanceInfoVo.setAppId(appId);
        byteDanceInfoVo.setLoginVo(userApi.checkRegister(registerBo).getResult());

        Map<String, String> sessionKeyMap = new HashMap<>(16);
        sessionKeyMap.put("openId", sessionVo.getOpenid());
        sessionKeyMap.put("unionId", sessionVo.getUnionid());
        sessionKeyMap.put("session_key", sessionVo.getSession_key());
        sessionKeyMap.put("anonymous_openid", sessionVo.getAnonymous_openid());
        redisService.getHashOps().putAll(RedisKey.BYTE_DANCE_SESSION.getKey(appId), sessionKeyMap);
        redisService.getHashOps().getOperations().expire(RedisKey.BYTE_DANCE_SESSION.getKey(appId), 1, TimeUnit.DAYS);
        return byteDanceInfoVo;
    }

    private ByteDanceSessionVo getByteDanceSession(String appId,String code){
        ParamException.isTrue(!StringUtils.hasText(code),"登录凭证不能为空");

        String secret = redisService.getHashOps().get(RedisKey.BYTE_DANCE_KEY.getKey(appId), "appSecret");
        ParamException.isTrue(!StringUtils.hasText(secret),"配置不存在");

        ByteDanceSessionVo byteDanceSessionVo = restTemplate.getForObject(Constant.BYTE_DANCE_SESSION, ByteDanceSessionVo.class, appId, secret, code);
        //ByteDanceSessionVo byteDanceSessionVo = byteDanceApi.jscode2session(appId, secret, code, anonymous_code);
        log.info("字节登录接口返回数据：[{}]", JSON.toJSONString(byteDanceSessionVo));
        ParamException.isFalse(Integer.valueOf(0).equals(byteDanceSessionVo.getError()), byteDanceSessionVo.getMessage());
        return byteDanceSessionVo;
    }

    public byte[] createQRCode(ByteQRCodeBo bo) {
        ParamException.isNull(bo);
        bo.setAccess_token(token());
        return restTemplate.postForObject(Constant.BYTE_DANCE_QRCODE, bo, byte[].class);
    }

    public ByteDanceOrderVo createOrder(ByteOrderBo bo) {
        return restTemplate.postForObject(Constant.BYTE_DANCE_CREATE_ORDER, bo, ByteDanceOrderVo.class);
    }

    public ByteDanceQueryOrderVo queryOrder(ByteOrderBo bo) {
        return restTemplate.postForObject(Constant.BYTE_DANCE_QUERY_ORDER, bo, ByteDanceQueryOrderVo.class);
    }

    public ByteDanceRefundVo createRefund(ByteRefundBo bo) {
        return restTemplate.postForObject(Constant.BYTE_DANCE_CREATE_REFUND, bo, ByteDanceRefundVo.class);
    }

    public ByteDanceQueryRefundVo queryRefund(ByteRefundBo bo) {
        return restTemplate.postForObject(Constant.BYTE_DANCE_QUERY_REFUND, bo, ByteDanceQueryRefundVo.class);
    }
}
